package net.muchine.web.front.controller.admin;

import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import net.muchine.core.domain.user.Group;
import net.muchine.core.domain.user.GroupUser;
import net.muchine.core.domain.user.User;
import net.muchine.core.service.user.GroupService;
import net.muchine.core.service.user.GroupUserService;
import net.muchine.core.service.user.UserService;
import net.muchine.core.support.util.Debugger;
import net.muchine.web.common.Pages;
import net.muchine.web.front.controller.AdminController;
import net.muchine.web.front.model.AssignedUsers;

@Controller
@SessionAttributes("group")
public class GroupController extends AdminController {
	@Autowired private GroupService groupService;
	@Autowired private UserService userService;
	@Autowired private GroupUserService groupUserService;
		
	private static final String MODEL_GROUPS = "groups";
	private static final String MODEL_GROUP = "group";
	
	@RequestMapping("/groups")
	public String listGroups(ModelMap model) {
		List<Group> groups = groupService.selectAll();
		model.put("groups", groups);
		return Pages.ADMIN_GROUPS_LIST;
	}
	
	@RequestMapping("/groups/new")
	public String newGroup(ModelMap model) {
		model.put("group", new Group());
		return Pages.ADMIN_GROUPS_NEW;
	}
	
	@RequestMapping("/groups/{seq}/edit")
	public String editGroup(
			@PathVariable Long seq,
			ModelMap model) {
		
		Group group = groupService.find(seq);
		model.put("group", group);
		
		List<User> users = userService.selectAll();
		model.put("users", users);
		
		List<User> assignedUsers = groupUserService.selectUsers(seq);
		model.put("assignedUsers", assignedUsers);
		
		return Pages.ADMIN_GROUPS_EDIT;
	}
	
	@RequestMapping("/groups/{seq}/users")
	@ResponseBody
	public User assignUsers(
			@PathVariable Long seq,
			@RequestBody AssignedUsers users) {
		for (Long userSeq : users.getUsers()) {
			GroupUser groupUser = new GroupUser();
			groupUser.setGroupSeq(seq);
			groupUser.setUserSeq(userSeq);
			
//			groupUserService.create(groupUser);
			
			log.info("user [seq: " + userSeq + "] has been assigned to the group [" + seq + "]");
		}
		
		// Return users assigned to this group
		List<User> assignedUsers = groupUserService.selectUsers(seq);
		
		User user = new User();
		user.setId("abcd");
		return user;
	}
	
	@RequestMapping(value="/groups", method=RequestMethod.POST)
	public String createGroup(
			  @ModelAttribute @Valid Group group
			, BindingResult result
			, @RequestParam(value="continue", required=false) String continueCreate
			, ModelMap model
			, Locale locale) {
		if (result.hasErrors()) {
			this.logErrors(result);
			return Pages.ADMIN_GROUPS_NEW;
		}
		
		if (group.getId() == null) group.setId(group.getName());
		
		groupService.create(group);
		log.info("A group has been created... name: " + group.getName());
		
		this.setSuccessCreationNotice(model, locale);		
		if (continueCreate != null)
			return newGroup(model);
		else
			return listGroups(model);
	}
	
	@RequestMapping(value="/groups/{seq}/edit", method=RequestMethod.POST)
	public String updateGroup(
			  @PathVariable String seq
			, @ModelAttribute @Valid Group group
			, BindingResult result
			, ModelMap model
			, Locale locale
			, SessionStatus status) {
		if (result.hasErrors()) {
			this.logErrors(result);
			return Pages.ADMIN_GROUPS_EDIT;
		}
		
		group.setId(group.getName());
		log.info(Debugger.entityToString(group));
		
		groupService.update(group);
		status.setComplete();
		log.info("A group has been updated... name: " + group.getName());
		
		this.setSuccessCreationNotice(model, locale);
		return this.listGroups(model);
	}
	
	@RequestMapping("/groups/{seq}/delete")
	public String deleteGroup(@PathVariable long seq) {
		groupService.delete(seq);
		log.info("A group has been deleted... seq: " + seq);
		
		return "redirect:/admin/groups";
	}
}
